package com.moter.demo01.requirements.re_0905.question_ioc.annotation;

import com.moter.demo01.requirements.re_0905.question_ioc.xml.MoterService;

import java.io.File;
import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


public class MoterBeanFactory implements BeanFactory, BeanRegister, BeanDI {

    private String path;
    private ConcurrentHashMap<String, Object> beans = null;
    private final String rootPath = "src.main.java.";
    private final String DEFAULT_PATH = rootPath + this.getClass().getPackage().getName();
    List<Class<?>> classes = null;

    public MoterBeanFactory() {
        path = DEFAULT_PATH;

    }

    public MoterBeanFactory(String path) {
        this.path = path;
    }

    public void init() throws Exception {
        classes = new ArrayList<>();
        saoBao(path.replace(".", "\\"));
        register();
        inject();
    }

    @Override
    public Object getBean(String beanId) throws Exception {
        Objects.requireNonNull(beanId, "不能为空或为null\t" + beanId);
        if (!beans.containsKey(beanId))
            throw new Exception("没有这个bean");
        return beans.get(beanId);

    }

    @Override
    public void inject() throws IllegalAccessException {
        Set<Map.Entry<String, Object>> entries = beans.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            isFieldAnnotated(entry.getValue());
        }
    }

    @Override
    public void register() throws InstantiationException, IllegalAccessException {
        beans = new ConcurrentHashMap<>();
        for (Class<?> aClass : classes) {
            isClassAnnotated(aClass);
        }
    }

    public void isFieldAnnotated(Object o) throws IllegalAccessException {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            if(declaredField.getAnnotation(MoterAutowired.class)!=null){
                declaredField.setAccessible(true);
                declaredField.set(o,beans.get(declaredField.getName()));
                System.out.println("123");
            }
        }
    }

    private void isClassAnnotated(Class<?> c) throws IllegalAccessException, InstantiationException {
        if (c.getAnnotation(MoterService.class) != null) {
            String name = c.getSimpleName();
            name = name.substring(0, 1).toLowerCase() + name.substring(1, name.length());
            beans.put(name, c.newInstance());
        }
    }

    public void saoBao(String path) throws Exception {
        File file = new File(path);
        if (!file.exists() || !file.isDirectory()) {
            throw new NoSuchFileException("不存在该包\t" + path);
        }
        File[] files = file.listFiles(File::isFile);
        for (File file1 : files) {
            if (file1.getPath().endsWith(".java")) {
                String filePath = file.getPath() + "\\" + file1.getName();
                filePath = filePath.replace("\\", ".");
                filePath = filePath.split(rootPath)[1].replace(".java", "");
                classes.add(Class.forName(filePath));
            }
        }
    }

    public static void main(String[] args) throws Exception {
        MoterBeanFactory factory = new MoterBeanFactory();
        factory.init();
        factory.beans.entrySet().forEach(n-> System.out.println(n.getKey()+"\t"+n.getValue()));
        MoterTestFather moterTestFather = (MoterTestFather) factory.getBean("moterTestFather");
        System.out.println(moterTestFather);
        moterTestFather.write();
    }
}
